Passed
Push — master ( 20a5af...c66660 )
by EMP
01:14
created

main.js ➔ getCountryFlag   A

Complexity

Conditions 1

Size

Total Lines 6
Code Lines 4

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
eloc 4
dl 0
loc 6
rs 10
c 0
b 0
f 0
cc 1
1
"use strict";
2
3
sodium.ready.then(function() {
4
5
const ae = new AllEars(function(ok) {
6
	if (ok) {
7
		document.getElementById("btn_enter").disabled = false;
8
	} else {
9
		console.log("Failed to load All-Ears");
0 ignored issues
show
Debugging Code introduced by
console.log looks like debug code. Are you sure you do not want to remove it?
Loading history...
10
	}
11
});
12
13
let page=0;
14
15
function navMenu(num) {
16
	document.getElementById("div_readmsg").hidden = true;
17
18
	const b = document.getElementsByTagName("nav")[0].getElementsByTagName("button");
19
	const d = document.getElementsByClassName("maindiv");
20
21
	for (let i = 0; i < 5; i++) {
22
		if (i === num) {
23
			b[i].disabled = true;
24
			d[i].hidden = false;
25
		} else {
26
			b[i].disabled = false;
27
			d[i].hidden = true;
28
		}
29
	}
30
}
31
32
function getCountryFlag(countryCode) {
33
	return sodium.to_string(new Uint8Array([
34
		240, 159, 135, 166 + countryCode.codePointAt(0) - 65,
35
		240, 159, 135, 166 + countryCode.codePointAt(1) - 65
36
	]));
37
}
38
39
function deleteButtonShow(show) {
40
	if (show) {
41
		document.getElementById("btn_msgdel").hidden = false;
42
		return;
43
	}
44
45
	const checkboxes = document.getElementById("tbd_inbox").getElementsByTagName("input");
46
	let checked = false;
47
48
	for (let j = 0; j < checkboxes.length; j++) {
49
		if (checkboxes[j].checked) {
50
			checked = true;
51
			break;
52
		}
53
	}
54
55
	document.getElementById("btn_msgdel").hidden = !checked;
56
}
57
58
function addIntMessage(i) {
59
	const tbl = document.getElementById("tbd_inbox");
60
	const row = tbl.insertRow(-1);
61
62
	const ts = ae.GetIntMsgTime(i);
63
	let cell = row.insertCell(-1);
64
	cell.setAttribute("data-ts", ts);
65
	cell.textContent = new Date(ts * 1000).toISOString().slice(0, 16).replace("T", " ");
66
	cell.className = "mono";
67
68
	cell = row.insertCell(-1);
69
	cell.textContent = ae.GetIntMsgTitle(i);
70
	cell.onclick = function() {
71
		navMenu(-1);
72
		document.getElementById("div_readmsg").hidden = false;
73
		document.getElementById("readmsg_head").hidden = false;
74
		document.getElementById("readmsg_levelinfo").hidden = false;
75
		document.getElementById("readmsg_extmsg").hidden = true;
76
77
		document.getElementById("readmsg_title").textContent = ae.GetIntMsgTitle(i);
78
		document.getElementById("readmsg_from").textContent  = ae.GetIntMsgFrom(i);
79
		document.getElementById("readmsg_to").textContent    = ae.GetIntMsgTo(i);
80
		document.getElementById("readmsg_body").textContent  = ae.GetIntMsgBody(i);
81
		document.getElementById("readmsg_level").textContent = ae.GetIntMsgLevel(i);
82
83
		document.getElementById("readmsg_from").className = (ae.GetIntMsgFrom(i).length === 16) ? "mono" : "";
84
		document.getElementById("readmsg_to").className = (ae.GetIntMsgTo(i).length === 16) ? "mono" : "";
85
	};
86
87
	// empty From1 cell
88
	row.insertCell(-1);
89
90
	cell = row.insertCell(-1);
91
	cell.textContent = ae.GetIntMsgFrom(i);
92
	cell.className = (ae.GetIntMsgFrom(i).length === 16) ? "mono" : "";
93
94
	cell = row.insertCell(-1);
95
	cell.textContent = ae.GetIntMsgTo(i);
96
	cell.className = (ae.GetIntMsgTo(i).length === 16) ? "mono" : "";
97
98
	cell = row.insertCell(-1);
99
	cell.innerHTML = "<input class=\"delMsg\" type=\"checkbox\" data-id=\"" + ae.GetIntMsgIdHex(i) + "\">";
100
	cell.children[0].onchange = function() {deleteButtonShow(this.checked);};
101
}
102
103
function addExtMessage(i) {
104
	const tbl = document.getElementById("tbd_inbox");
105
	const row = tbl.insertRow(-1);
106
107
	const ts = ae.GetExtMsgTime(i);
108
	let cell = row.insertCell(-1);
109
	cell.setAttribute("data-ts", ts);
110
	cell.textContent = new Date(ts * 1000).toISOString().slice(0, 16).replace("T", " ");
111
	cell.className = "mono";
112
113
	cell = row.insertCell(-1);
114
	cell.textContent = ae.GetExtMsgTitle(i);
115
	cell.onclick = function() {
116
		navMenu(-1);
117
		document.getElementById("div_readmsg").hidden = false;
118
		document.getElementById("readmsg_head").hidden = false;
119
		document.getElementById("readmsg_levelinfo").hidden = true;
120
		document.getElementById("readmsg_extmsg").hidden = false;
121
		document.getElementById("readmsg_greet").textContent = ae.GetExtMsgGreet(i);
122
		document.getElementById("readmsg_tls").textContent = ae.GetExtMsgTLS(i);
123
		document.getElementById("readmsg_ip").textContent = ae.GetExtMsgIp(i);
124
125
		document.getElementById("readmsg_country").textContent = ae.GetExtMsgCname(i) + " " + getCountryFlag(ae.GetExtMsgCcode(i));
126
127
		let flagText = "";
128
		if (!ae.GetExtMsgFlagPExt(i)) flagText += "<abbr title=\"The sender did not use the Extended (ESMTP) protocol\">SMTP</abbr> ";
129
		if (!ae.GetExtMsgFlagQuit(i)) flagText += "<abbr title=\"The sender did not issue the required QUIT command\">QUIT</abbr> ";
130
		if (ae.GetExtMsgFlagRare(i)) flagText += "<abbr title=\"The sender issued unusual command(s)\">RARE</abbr> ";
131
		if (ae.GetExtMsgFlagFail(i)) flagText += "<abbr title=\"The sender issued invalid command(s)\">FAIL</abbr> ";
132
		if (ae.GetExtMsgFlagPErr(i)) flagText += "<abbr title=\"The sender violated the protocol\">PROT</abbr> ";
133
		document.getElementById("readmsg_flags").innerHTML = flagText.trim();
134
135
		document.getElementById("readmsg_title").textContent = ae.GetExtMsgTitle(i);
136
		document.getElementById("readmsg_from").textContent = ae.GetExtMsgEnvFrom(i);
137
		document.getElementById("readmsg_to").textContent = ae.GetExtMsgEnvTo(i);
138
		document.getElementById("readmsg_body").innerHTML = ae.GetExtMsgBody(i);
139
		document.getElementById("readmsg_headers").textContent = ae.GetExtMsgHeaders(i);
140
141
		document.getElementById("readmsg_from").className = "";
142
		document.getElementById("readmsg_to").className = (ae.GetExtMsgEnvTo(i).length === 16) ? "mono" : "";
143
	};
144
145
	const from = ae.GetExtMsgHdrFrom(i);
146
	const from2 = from.substring(from.indexOf("@") + 1);
147
148
	cell = row.insertCell(-1);
149
	cell.textContent = from.substring(0, from.indexOf("@"));
150
151
	const flag = document.createElement("abbr");
152
	flag.textContent = getCountryFlag(ae.GetExtMsgCcode(i));
153
	flag.title = ae.GetExtMsgCname(i);
154
155
	const fromText = document.createElement("span");
156
	fromText.textContent = " " + from2;
157
158
	cell = row.insertCell(-1);
159
	cell.appendChild(flag);
160
	cell.appendChild(fromText);
161
162
	cell = row.insertCell(-1);
163
	cell.textContent = ae.GetExtMsgEnvTo(i);
164
	cell.className = (ae.GetExtMsgEnvTo(i).length === 16) ? "mono" : "";
165
166
	cell = row.insertCell(-1);
167
	cell.innerHTML = "<input class=\"delMsg\" type=\"checkbox\" data-id=\"" + ae.GetExtMsgIdHex(i) + "\">";
168
	cell.children[0].onchange = function() {deleteButtonShow(this.checked);};
169
}
170
171
function addMessages() {
172
	const maxExt = ae.GetExtMsgCount();
173
	const maxInt = ae.GetIntMsgCount();
174
175
	let numExt = 0;
176
	let numInt = 0;
177
178
	//TODO handle sent messages separately
179
180
	for (let i = 0; i < (page * 20) + 20; i++) {
181
		const tsInt = (numInt < maxInt) ? ae.GetIntMsgTime(numInt) : 0;
182
		const tsExt = (numExt < maxExt) ? ae.GetExtMsgTime(numExt) : 0;
183
		if (tsInt === 0 && tsExt === 0) break;
184
185
		if (tsInt !== 0 && (tsExt === 0 || tsInt > tsExt)) {
186
			if (i < (page * 20)) {
187
				numInt++;
188
				continue;
189
			}
190
191
			addIntMessage(numInt);
192
			numInt++;
193
		} else if (tsExt !== 0) {
194
			if (i < (page * 20)) {
195
				numExt++;
196
				continue;
197
			}
198
199
			addExtMessage(numExt);
200
			numExt++;
201
		}
202
	}
203
}
204
205
function addFile(num) {
206
	const table = document.getElementById("tbody_files");
207
	const row = table.insertRow(-1);
208
209
	let cell = row.insertCell(-1);
210
	cell.textContent = new Date(ae.GetUplMsgTime(num) * 1000).toISOString().slice(0, 10)
211
212
	cell = row.insertCell(-1);
213
	cell.textContent = ae.GetUplMsgBytes(num) / 1024;
214
215
	cell = row.insertCell(-1);
216
	cell.textContent = ae.GetUplMsgTitle(num);
217
218
	cell = row.insertCell(-1);
219
	cell.innerHTML = "<button type=\"button\">D</button>";
220
	cell.children[0].onclick = function() {
221
		const a = document.createElement("a");
222
		a.href = URL.createObjectURL(new Blob([ae.GetUplMsgBody(num).buffer]));
223
		a.download = ae.GetUplMsgTitle(num);
224
		a.click();
225
226
		URL.revokeObjectURL(a.href);
227
		a.href = "";
228
		a.download = "";
229
	};
230
231
	cell = row.insertCell(-1);
232
	cell.innerHTML = "<button type=\"button\">X</button>";
233
	cell.children[0].onclick = function() {
234
		ae.Message_Delete([ae.GetUplMsgIdHex(num)], function(error) {
235
			if (error === 0) {
236
				row.remove();
237
			} else {
238
				console.log("Failed deleting file");
0 ignored issues
show
Debugging Code introduced by
console.log looks like debug code. Are you sure you do not want to remove it?
Loading history...
239
			}
240
		});
241
	};
242
}
243
244
function destroyAccount(upk_hex) {
245
	const tbl = document.getElementById("tbody_admin");
246
247
	let rowid = -1;
248
249
	for (let i = 0; i < tbl.rows.length; i++) {
250
		if (upk_hex === tbl.rows[i].cells[0].textContent) {
251
			rowid = i;
252
			break;
253
		}
254
	}
255
256
	if (rowid === -1) return;
257
258
	ae.Account_Delete(upk_hex, function(error) {
259
		if (error === 0) {
260
			tbl.deleteRow(rowid);
261
		} else {
262
			console.log("Failed to destroy account");
0 ignored issues
show
Debugging Code introduced by
console.log looks like debug code. Are you sure you do not want to remove it?
Loading history...
263
		}
264
	});
265
}
266
267
function setAccountLevel(upk_hex, level) {
268
	const tbl = document.getElementById("tbody_admin");
269
270
	let rowid = -1;
271
272
	for (let i = 0; i < tbl.rows.length; i++) {
273
		if (tbl.rows[i].cells[0].textContent === upk_hex) {
274
			rowid = i;
275
			break;
276
		}
277
	}
278
279
	if (rowid === -1) return;
280
281
	ae.Account_Update(upk_hex, level, function(error) {
282
		if (error !== 0) {
283
			console.log("Failed to set account level");
0 ignored issues
show
Debugging Code introduced by
console.log looks like debug code. Are you sure you do not want to remove it?
Loading history...
284
			return;
285
		}
286
287
		tbl.rows[rowid].cells[4].textContent = level;
288
289
		if (level === 0) {
290
			tbl.rows[rowid].cells[5].children[0].disabled = false;
291
			tbl.rows[rowid].cells[6].children[0].disabled = true;
292
		} else if (level === ae.GetLevelMax()) {
293
			tbl.rows[rowid].cells[5].children[0].disabled = true;
294
			tbl.rows[rowid].cells[6].children[0].disabled = false;
295
		} else {
296
			tbl.rows[rowid].cells[5].children[0].disabled = false;
297
			tbl.rows[rowid].cells[6].children[0].disabled = false;
298
		}
299
300
		const pkHex = ae.Admin_GetUserPkHex(rowid);
301
		const currentLevel = ae.Admin_GetUserLevel(rowid);
302
		tbl.rows[rowid].cells[5].children[0].onclick = function() {setAccountLevel(pkHex, currentLevel + 1);};
303
		tbl.rows[rowid].cells[6].children[0].onclick = function() {setAccountLevel(pkHex, currentLevel - 1);};
304
	});
305
}
306
307
function deleteAddress(addr) {
308
	let btns = document.getElementById("tbody_opt_addr").getElementsByTagName("button");
309
	for (let i = 0; i < btns.length; i++) btns[i].disabled = true;
310
311
	let addressToDelete = -1;
312
313
	for (let i = 0; i < ae.GetAddressCount(); i++) {
314
		if (addr === ae.GetAddress(i)) {
315
			addressToDelete = i;
316
			break;
317
		}
318
	}
319
320
	if (addressToDelete === -1) return;
321
322
	ae.Address_Delete(addressToDelete, function(error) {
323
		if (error !== 0) {
324
			console.log("Failed to delete address");
0 ignored issues
show
Debugging Code introduced by
console.log looks like debug code. Are you sure you do not want to remove it?
Loading history...
325
			return;
326
		}
327
328
		document.getElementById("tbody_opt_addr").deleteRow(addressToDelete);
329
		document.getElementById("send_from").remove(addressToDelete);
330
331
		document.getElementById("addr_use_normal").textContent = ae.GetAddressCountNormal();
332
		document.getElementById("addr_use_shield").textContent = ae.GetAddressCountShield();
333
334
		if (ae.GetAddressCountNormal() < ae.GetLimitNormalA(ae.GetUserLevel())) document.getElementById("btn_newaddress").disabled = false;
335
		if (ae.GetAddressCountShield() < ae.GetLimitShieldA(ae.GetUserLevel())) document.getElementById("btn_newshieldaddress").disabled = false;
336
337
		ae.Private_Update(function(error2) {
338
			if (!error2 !== 0) console.log("Failed to update the Private field");
0 ignored issues
show
Debugging Code introduced by
console.log looks like debug code. Are you sure you do not want to remove it?
Loading history...
339
340
			btns = document.getElementById("tbody_opt_addr").getElementsByTagName("button");
341
			for (let i = 0; i < btns.length; i++) btns[i].disabled = false;
342
		});
343
	});
344
}
345
346
function shieldMix(addr) {
347
	let newAddr = "";
348
349
	for (let i = 0; i < 16; i++) {
350
		switch (addr.charAt(i)) {
351
			case '1':
352
				newAddr += "1iIlL".charAt(Math.floor(Math.random() * 5));
353
				break;
354
			case '0':
355
				newAddr += "0oO".charAt(Math.floor(Math.random() * 3));
356
				break;
357
			case 'w':
358
				newAddr += "VvWw".charAt(Math.floor(Math.random() * 4));
359
				break;
360
			default:
361
				newAddr += (Math.random() > 0.5) ? addr.charAt(i) : addr.charAt(i).toUpperCase();
362
		}
363
	}
364
365
	return newAddr;
366
}
367
368
function addAddress(num) {
369
	const addrTable = document.getElementById("tbody_opt_addr");
370
	const row = addrTable.insertRow(-1);
371
372
	let cell = row.insertCell(-1);
373
	cell.textContent = ae.GetAddress(num);
374
	if (cell.textContent.length === 16) cell.className = "mono";
375
	cell.onclick = function() {
376
		if (cell.textContent.length === 16)
377
			navigator.clipboard.writeText(shieldMix(cell.textContent) + "@" + ae.GetDomainEml());
378
		else
379
			navigator.clipboard.writeText(cell.textContent + "@" + ae.GetDomainEml());
380
	};
381
382
	cell = row.insertCell(-1);
383
	cell.innerHTML = ae.GetAddressAccExt(num) ? "<input type=\"checkbox\" checked=\"checked\">" : "<input type=\"checkbox\">";
384
385
	cell = row.insertCell(-1);
386
	cell.innerHTML = ae.GetAddressAccInt(num) ? "<input type=\"checkbox\" checked=\"checked\">" : "<input type=\"checkbox\">";
387
388
	cell = row.insertCell(-1);
389
	cell.innerHTML = "<button type=\"button\">X</button>";
390
	cell.children[0].onclick = function() {deleteAddress(ae.GetAddress(num));};
391
392
	const opt = document.createElement("option");
393
	opt.value = ae.GetAddress(num);
394
	opt.textContent = ae.GetAddress(num) + "@" + ae.GetDomainEml();
395
	document.getElementById("send_from").appendChild(opt);
396
}
397
398
function clearMessages() {
399
	document.getElementById("tbd_inbox").innerHTML = "";
400
	document.getElementById("tbd_snbox").innerHTML = "";
401
	document.getElementById("tbody_files").innerHTML = "";
402
}
403
404
function delMsgs(tblName, btnName) {
405
	const cbs = document.getElementsByClassName("delMsg");
406
	const ids = [];
407
408
	for (let i = 0; i < cbs.length; i++) {
409
		if (cbs[i].checked) ids.push(cbs[i].getAttribute("data-id"));
410
	}
411
412
	if (ids.length > 0) ae.Message_Delete(ids, function(error) {
413
		if (error === 0) {
414
			clearMessages();
415
			addMessages();
416
			document.getElementById(btnName).hidden = true;
417
		} else {
418
			console.log("Failed to delete messages");
0 ignored issues
show
Debugging Code introduced by
console.log looks like debug code. Are you sure you do not want to remove it?
Loading history...
419
		}
420
	});
421
}
422
423
function deleteContact(email) {
424
	const tbl = document.getElementById("tbody_notes_contact");
425
	const rows = tbl.rows;
426
427
	for (let i = 0; i < rows.length; i++) {
428
		if (email === rows[i].cells[0].textContent) {
429
			ae.DeleteContact(i);
430
			tbl.deleteRow(i);
431
			break;
432
		}
433
	}
434
435
	document.getElementById("btn_savenotes").hidden = false;
436
}
437
438
function addContactToTable(mail, name, note) {
439
	const contactTable = document.getElementById("tbody_notes_contact");
440
	const row = contactTable.insertRow(-1);
441
	const cellMail = row.insertCell(-1);
442
	const cellName = row.insertCell(-1);
443
	const cellNote = row.insertCell(-1);
444
	const cellBtnD = row.insertCell(-1);
445
446
	cellMail.className = "left";
447
	cellName.className = "left";
448
	cellNote.className = "left";
449
450
	cellMail.textContent = mail;
451
	cellName.textContent = name;
452
	cellNote.textContent = note;
453
	cellBtnD.innerHTML = "<button type=\"button\">X</button>";
454
455
	cellBtnD.onclick = function() {deleteContact(mail);};
456
}
457
458
function addRowAdmin(num) {
459
	const table = document.getElementById("tbody_admin");
460
461
	const row = table.insertRow(-1);
462
	const cellPk = row.insertCell(-1);
463
	const cellMb = row.insertCell(-1);
464
	const cellNa = row.insertCell(-1);
465
	const cellSa = row.insertCell(-1);
466
	const cellLv = row.insertCell(-1);
467
	const cellBtnPl = row.insertCell(-1);
468
	const cellBtnMn = row.insertCell(-1);
469
	const cellBtnDe = row.insertCell(-1);
470
471
	cellPk.textContent = ae.Admin_GetUserPkHex(num);
472
	cellMb.textContent = ae.Admin_GetUserSpace(num);
473
	cellNa.textContent = ae.Admin_GetUserNAddr(num);
474
	cellSa.textContent = ae.Admin_GetUserSAddr(num);
475
	cellLv.textContent = ae.Admin_GetUserLevel(num);
476
	cellBtnPl.innerHTML = "<button type=\"button\">+</button>";
477
	cellBtnMn.innerHTML = "<button type=\"button\">-</button>";
478
	cellBtnDe.innerHTML = "<button type=\"button\">X</button>";
479
480
	cellPk.className = "mono";
481
	if (ae.Admin_GetUserLevel(num) === ae.GetLevelMax()) cellBtnPl.children[0].disabled = true;
482
	if (ae.Admin_GetUserLevel(num) === 0) cellBtnMn.children[0].disabled = true;
483
484
	const pkHex = ae.Admin_GetUserPkHex(num);
485
	const currentLevel = ae.Admin_GetUserLevel(num);
486
	cellBtnPl.children[0].onclick = function() {setAccountLevel(pkHex, currentLevel + 1);};
487
	cellBtnMn.children[0].onclick = function() {setAccountLevel(pkHex, currentLevel - 1);};
488
	cellBtnDe.children[0].onclick = function() {destroyAccount(pkHex);};
489
}
490
491
function reloadInterface() {
492
	if (!ae.IsUserAdmin()) document.getElementById("btn_toadmin").hidden = true;
493
	document.getElementById("div_begin").hidden = true;
494
	document.getElementById("div_allears").hidden = false;
495
496
	clearMessages();
497
	document.getElementById("tbody_admin").innerHTML = "";
498
	document.getElementById("tbody_files").innerHTML = "";
499
	document.getElementById("tbody_notes_contact").innerHTML = "";
500
	document.getElementById("tbody_opt_addr").innerHTML = "";
501
502
	// Contacts
503
	for (let i = 0; i < ae.GetContactCount(); i++) {
504
		addContactToTable(
505
			ae.GetContactMail(i),
506
			ae.GetContactName(i),
507
			ae.GetContactNote(i)
508
		);
509
	}
510
511
	// Addresses
512
	for (let i = 0; i < ae.GetAddressCount(); i++) {
513
		addAddress(i);
514
	}
515
516
	document.getElementById("addr_use_normal").textContent = ae.GetAddressCountNormal();
517
	document.getElementById("addr_use_shield").textContent = ae.GetAddressCountShield();
518
	document.getElementById("addr_max_normal").textContent = ae.GetLimitNormalA(ae.GetUserLevel());
519
	document.getElementById("addr_max_shield").textContent = ae.GetLimitShieldA(ae.GetUserLevel());
520
521
	if (ae.GetAddressCountNormal() >= ae.GetLimitNormalA(ae.GetUserLevel())) document.getElementById("btn_newaddress").disabled = true;
522
	if (ae.GetAddressCountShield() >= ae.GetLimitShieldA(ae.GetUserLevel())) document.getElementById("btn_newshieldaddress").disabled = true;
523
524
	if (ae.IsUserAdmin()) {
525
		const tblLimits = document.getElementById("tbl_limits");
526
		for (let i = 0; i < 4; i++) {
527
			tblLimits.rows[i].cells[1].children[0].value = ae.GetStorageLimit(i);
528
			tblLimits.rows[i].cells[2].children[0].value = ae.GetLimitNormalA(i);
529
			tblLimits.rows[i].cells[3].children[0].value = ae.GetLimitShieldA(i);
530
		}
531
532
		document.getElementById("btn_admin_savelimits").onclick = function() {
533
			const storageLimit = [];
534
			const addrNrmLimit = [];
535
			const addrShdLimit = [];
536
537
			for (let i = 0; i < 4; i++) {
538
				storageLimit[i] = tblLimits.rows[i].cells[1].children[0].value;
539
				addrNrmLimit[i] = tblLimits.rows[i].cells[2].children[0].value;
540
				addrShdLimit[i] = tblLimits.rows[i].cells[3].children[0].value;
541
			}
542
543
			ae.SetLimits(storageLimit, addrNrmLimit, addrShdLimit, function(error) {
544
				if (error !== 0) {
545
					console.log("Failed to update limits");
0 ignored issues
show
Debugging Code introduced by
console.log looks like debug code. Are you sure you do not want to remove it?
Loading history...
546
				}
547
			});
548
		};
549
550
		for (let i = 0; i < ae.Admin_GetUserCount(); i++) {
551
			addRowAdmin(i);
552
		}
553
	}
554
}
555
556
document.getElementById("btn_inbox_prev").onclick = function() {
557
	if (page > 0) {
558
		page--;
559
		clearMessages();
560
		addMessages();
561
		this.disabled = (page === 0);
562
	}
563
};
564
565
document.getElementById("btn_inbox_next").onclick = function() {
566
// TODO: Check if page too high
567
//	if (page > 0) {
568
		page++;
569
		clearMessages();
570
		addMessages();
571
		document.getElementById("btn_inbox_prev").disabled = false;
572
//	}
573
};
574
575
document.getElementById("btn_enter").onclick = function() {
576
	const txtSkey = document.getElementById("txt_skey");
577
	if (!txtSkey.reportValidity()) return;
578
579
	const btn = this;
580
	btn.disabled = true;
581
582
	ae.SetKeys(txtSkey.value, function(success) {
583
		if (!success) {
584
			console.log("Invalid format for key");
0 ignored issues
show
Debugging Code introduced by
console.log looks like debug code. Are you sure you do not want to remove it?
Loading history...
585
			btn.disabled = false;
586
			return;
587
		}
588
589
		ae.Message_Browse(false, true, function(statusBrowse) {
590
			if (statusBrowse !== 0) {
591
				console.log("Failed to enter");
0 ignored issues
show
Debugging Code introduced by
console.log looks like debug code. Are you sure you do not want to remove it?
Loading history...
592
				btn.disabled = false;
593
				return;
594
			}
595
596
			txtSkey.value = "";
597
			reloadInterface();
598
			document.getElementById("btn_refresh").click();
599
		});
600
	});
601
};
602
603
document.getElementById("btn_refresh").onclick = function() {
604
	const btn = this;
605
	btn.disabled = true;
606
607
	ae.Message_Browse(true, false, function(error) {
608
		if (error === 0) {
609
			clearMessages();
610
			addMessages();
611
			for (let i = ae.GetUplMsgCount() - 1; i >= 0; i--) {addFile(i);}
612
		} else {
613
			console.log("Failed to refresh");
0 ignored issues
show
Debugging Code introduced by
console.log looks like debug code. Are you sure you do not want to remove it?
Loading history...
614
		}
615
616
		btn.disabled = false;
617
	});
618
};
619
620
document.getElementById("btn_contact_add").onclick = function() {
621
	const txtMail = document.getElementById("txt_newcontact_mail");
622
	const txtName = document.getElementById("txt_newcontact_name");
623
	const txtNote = document.getElementById("txt_newcontact_note");
624
625
	addContactToTable(txtMail.value, txtName.value, txtNote.value);
626
	ae.AddContact(txtMail.value, txtName.value, txtNote.value);
627
628
	txtMail.value = "";
629
	txtName.value = "";
630
	txtNote.value = "";
631
632
	document.getElementById("btn_savenotes").hidden = false;
633
};
634
635
document.getElementById("btn_savenotes").onclick = function() {
636
	ae.Private_Update(function(error) {
637
		if (error === 0) {
638
			document.getElementById("btn_savenotes").hidden = true;
639
		} else {
640
			console.log("Failed to save note data");
0 ignored issues
show
Debugging Code introduced by
console.log looks like debug code. Are you sure you do not want to remove it?
Loading history...
641
		}
642
	});
643
};
644
645
document.getElementById("btn_msgdel").onclick = function() {
646
	delMsgs("tbody_inbox", "btn_msgdel");
647
};
648
649
document.getElementById("btn_sentdel").onclick = function() {
650
	delMsgs("tbody_sentbox", "btn_sentdel");
651
};
652
653
document.getElementById("btn_send").onclick = function() {
654
	const btn = this;
655
	btn.disabled = true;
656
657
	const sfrom = document.getElementById("send_from");
658
	const stitle = document.getElementById("send_title");
659
	const sto = document.getElementById("send_to");
660
	const sbody = document.getElementById("send_body");
661
662
	if (!stitle.reportValidity() || !sto.reportValidity() || !sbody.reportValidity()) return;
663
664
	ae.Message_Create(stitle.value, sbody.value, sfrom.value, sto.value, null, function(error) {
665
		if (error === 0) {
666
			stitle.value = "";
667
			sto.value = "";
668
			sbody.value = "";
669
		} else {
670
			console.log("Failed sending message");
0 ignored issues
show
Debugging Code introduced by
console.log looks like debug code. Are you sure you do not want to remove it?
Loading history...
671
		}
672
673
		btn.disabled = false;
674
	});
675
};
676
677
document.getElementById("btn_newaddress").onclick = function() {
678
	if (ae.GetAddressCountNormal() >= ae.GetLimitNormalA(ae.GetUserLevel())) return;
679
680
	const txtNewAddr = document.getElementById("txt_newaddress");
681
	if (!txtNewAddr.reportValidity()) return;
682
683
	const btnN = document.getElementById("btn_newaddress");
684
	const btnS = document.getElementById("btn_newshieldaddress");
685
	btnN.disabled = true;
686
	btnS.disabled = true;
687
688
	ae.Address_Create(txtNewAddr.value, function(error1) {
689
		if (error1 === 0) {
690
			ae.Private_Update(function(error2) {
691
				document.getElementById("addr_use_normal").textContent = ae.GetAddressCountNormal();
692
				addAddress(ae.GetAddressCount() - 1);
693
				txtNewAddr.value = "";
694
695
				if (error2 !== 0) console.log("Failed to update the Private field");
0 ignored issues
show
Debugging Code introduced by
console.log looks like debug code. Are you sure you do not want to remove it?
Loading history...
696
				if (ae.GetAddressCountNormal() < ae.GetLimitNormalA(ae.GetUserLevel())) btnN.disabled = false;
697
				if (ae.GetAddressCountShield() < ae.GetLimitShieldA(ae.GetUserLevel())) btnS.disabled = false;
698
			});
699
		} else {
700
			console.log("Failed to add address");
0 ignored issues
show
Debugging Code introduced by
console.log looks like debug code. Are you sure you do not want to remove it?
Loading history...
701
			if (ae.GetAddressCountNormal() < ae.GetLimitNormalA(ae.GetUserLevel())) btnN.disabled = false;
702
			if (ae.GetAddressCountShield() < ae.GetLimitShieldA(ae.GetUserLevel())) btnS.disabled = false;
703
		}
704
	});
705
};
706
707
document.getElementById("btn_newshieldaddress").onclick = function() {
708
	if (ae.GetLimitShieldA() >= ae.GetLimitShieldA(ae.GetUserLevel())) return;
709
710
	const btnN = document.getElementById("btn_newaddress");
711
	const btnS = document.getElementById("btn_newshieldaddress");
712
	btnN.disabled = true;
713
	btnS.disabled = true;
714
715
	ae.Address_Create("SHIELD", function(error1) {
716
		if (error1 !== 0) {
717
			console.log("Failed to add Shield address");
0 ignored issues
show
Debugging Code introduced by
console.log looks like debug code. Are you sure you do not want to remove it?
Loading history...
718
			if (ae.GetAddressCountNormal() < ae.GetLimitNormalA(ae.GetUserLevel())) btnN.disabled = false;
719
			if (ae.GetAddressCountShield() < ae.GetLimitShieldA(ae.GetUserLevel())) btnS.disabled = false;
720
			return;
721
		}
722
723
		ae.Private_Update(function(error2) {
724
			document.getElementById("addr_use_shield").textContent = ae.GetAddressCountShield();
725
			addAddress(ae.GetAddressCount() - 1);
726
727
			if (error2 !== 0) console.log("Failed to update the Private field");
0 ignored issues
show
Debugging Code introduced by
console.log looks like debug code. Are you sure you do not want to remove it?
Loading history...
728
			if (ae.GetAddressCountNormal() < ae.GetLimitNormalA(ae.GetUserLevel())) btnN.disabled = false;
729
			if (ae.GetAddressCountShield() < ae.GetLimitShieldA(ae.GetUserLevel())) btnS.disabled = false;
730
		});
731
	});
732
};
733
734
document.getElementById("btn_saveaddrdata").onclick = function() {
735
	const tbl = document.getElementById("tbody_opt_addr");
736
737
	for (let i = 0; i < tbl.rows.length; i++) {
738
		ae.SetAddressAccExt(i, tbl.rows[i].cells[1].firstChild.checked);
739
		ae.SetAddressAccInt(i, tbl.rows[i].cells[2].firstChild.checked);
740
	}
741
742
	ae.Address_Update(function(error) {
743
		if (error === 0) {
744
			document.getElementById("btn_saveaddrdata").hidden = true;
745
		} else {
746
			console.log("Failed to save address data");
0 ignored issues
show
Debugging Code introduced by
console.log looks like debug code. Are you sure you do not want to remove it?
Loading history...
747
		}
748
	});
749
};
750
751
document.getElementById("btn_admin_addaccount").onclick = function() {
752
	const txtPkey = document.getElementById("txt_newacc_pkey");
753
754
	if (!txtPkey.reportValidity()) return;
755
756
	const btn = document.getElementById("btn_admin_addaccount");
757
	btn.disabled = true;
758
759
	ae.Account_Create(txtPkey.value, function(error) {
760
		if (error === 0) {
761
			addRowAdmin(ae.Admin_GetUserCount() - 1);
762
			txtPkey.value = "";
763
		} else {
764
			console.log("Failed to add account");
0 ignored issues
show
Debugging Code introduced by
console.log looks like debug code. Are you sure you do not want to remove it?
Loading history...
765
		}
766
	});
767
768
	btn.disabled = false;
769
};
770
771
document.getElementById("btn_uploadfile").onclick = function() {
772
	const fileSelector = document.getElementById("upfile");
773
	const f = fileSelector.files[0];
774
775
	if (f.name.length + f.size > 8138) {
776
		console.log("Too large");
0 ignored issues
show
Debugging Code introduced by
console.log looks like debug code. Are you sure you do not want to remove it?
Loading history...
777
		fileSelector.value = null;
778
		return;
779
	}
780
781
	const btn = this;
782
	btn.disabled = true;
783
784
	const reader = new FileReader();
785
	reader.onload = function(e) {
0 ignored issues
show
Unused Code introduced by
The parameter e is not used and could be removed.

This check looks for parameters in functions that are not used in the function body and are not followed by other parameters which are used inside the function.

Loading history...
786
		const u8data = new Uint8Array(reader.result);
787
788
		ae.Message_Upload(true, f.name, u8data, function(error) {
789
			if (error === 0) {
790
				addFile(ae.GetFileCount() - 1);
791
				fileSelector.value = null;
792
			} else {
793
				console.log("Failed to upload file");
0 ignored issues
show
Debugging Code introduced by
console.log looks like debug code. Are you sure you do not want to remove it?
Loading history...
794
			}
795
796
			btn.disabled = false;
797
		});
798
	};
799
800
	reader.readAsArrayBuffer(f);
801
};
802
803
function navNotesMenu(num) {
804
	for (let i = 0; i < 3; i++) {
805
		if (i === num) {
806
			document.getElementById("div_notes").children[0].children[i].disabled = true;
807
			document.getElementById("div_notes").children[1 + i].hidden = false;
808
		} else {
809
			document.getElementById("div_notes").children[0].children[i].disabled = false;
810
			document.getElementById("div_notes").children[1 + i].hidden = true;
811
		}
812
	}
813
}
814
815
let btns = document.getElementsByTagName("nav")[0].getElementsByTagName("button");
816
btns[0].onclick = function() {navMenu(0);};
817
btns[1].onclick = function() {navMenu(1);};
818
btns[2].onclick = function() {navMenu(2);};
819
btns[3].onclick = function() {navMenu(3);};
820
btns[4].onclick = function() {navMenu(4);};
821
822
btns = document.getElementById("div_notes").getElementsByTagName("button");
823
btns[0].onclick = function() {navNotesMenu(0);};
824
btns[1].onclick = function() {navNotesMenu(1);};
825
btns[2].onclick = function() {navNotesMenu(2);};
826
btns[3].onclick = function() {navNotesMenu(3);};
827
828
document.getElementById("txt_skey").onkeyup = function(e) {
829
	if (e.key === "Enter") document.getElementById("btn_enter").click();
830
};
831
832
navMenu(0);
833
834
});
835